package com.hualan.utils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class EntityFactory<T> {
    private Class<T> obj;
    private Object obj1;
    public EntityFactory(Class<T> obj) throws InstantiationException, IllegalAccessException {
        this.obj = obj;
        this.obj1 = this.obj.newInstance();
    }
    public T startCombine(ResultSet resultSet) throws SQLException, InvocationTargetException, NoSuchMethodException, IllegalAccessException, InstantiationException {
        Field[] fields = this.obj.getDeclaredFields();
        List<String> names = this.dealName(fields);
        Integer index = 0;
        for(Field field:fields){
            this.combieFileld(field,names.get(index++),resultSet);
        }
        return (T) this.obj1;
    }
    public List<String> dealName(Field[] fields){
        List<String> names = new ArrayList<>();
        for(Field field:fields){
            String name = field.getName();
            name ="set" + name.substring(0,1).toUpperCase()+name.substring(1);
            names.add(name);
        }
        return names;
    }
    public void combieFileld(Field field,String methodName,ResultSet resultSet) throws SQLException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        String type = field.getType().getSimpleName();
        if(type.equals("List"))return;
        if(type.equals("Integer")){
            Integer num = resultSet.getInt(field.getName());
            Method method = this.obj.getMethod(methodName,Integer.class);
            method.invoke(this.obj1,num);
        }else if(type.equals("String")){
            String num = resultSet.getString(field.getName());
            Method method = this.obj.getMethod(methodName,String.class);
            method.invoke(this.obj1,num);
        }else if(type.equals("Date")){
            Date num = resultSet.getDate(field.getName());
            Method method = this.obj.getMethod(methodName,Date.class);
            method.invoke(this.obj1,num);
        }else if(type.equals("Double")){
            Double num = resultSet.getDouble(field.getName());
            Method method = this.obj.getMethod(methodName,Double.class);
            method.invoke(this.obj1,num);
        }else if(type.equals("Byte")){
            Byte num = resultSet.getByte(field.getName());
            Method method = this.obj.getMethod(methodName,Byte.class);
            method.invoke(this.obj1,num);
        }else if(type.equals("LocalDateTime")){
            LocalDateTime num =(LocalDateTime) resultSet.getObject(field.getName());
            Method method = this.obj.getMethod(methodName,LocalDateTime.class);
            method.invoke(this.obj1,num);
        }else{
            EntityFactory entityFactory = new EntityFactory(field.getType());
            Object data = entityFactory.startCombine(resultSet);
            Method method = this.obj.getMethod(methodName,field.getType());
            method.invoke(this.obj1,data);
        }
    }
}
